package com.ytl.test;



import com.ytl.impl.MyCalculator;
import com.ytl.inner.Calculator;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**帮助calculator生成代理对象
 * jdk 反射包下
 * @author Jia Fa
 * @create 2021-12-13 12:35
 */
public class CalCulatorProxy {

    /**jdk动态代理的核心
     * 1基于 Proxy.newProxyInstance(classLoader, classes, invocationHandler)方法实现动态代理
     * 2方法执行器实现InvocationHandler接口       为传入的参数对象创建一个动态代理对象
     * CGLIB代理    Enhancer类中实现MethodInterceptor接口interceptor方法 (Object obj, Method method, Object[] args, MethodProxy proxy)
     * @param calculator 被代理对象
     * @return 代理对象
     */
    public static Calculator getProxy(Calculator calculator) {
        // 被代理类类加载器
        ClassLoader classLoader = calculator.getClass().getClassLoader();
        // 被代理类实现的接口
        Class<?>[] classes = calculator.getClass().getInterfaces();
        // 方法执行器  帮我们实现目标方法
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                /**
                 * Object proxy,    代理对象 jdk底层需要使用的 不可调用
                 * Method method,  当前将要执行的目标对象方法
                 * Object[] arg   目标方法的参数
                 */
                System.out.println("动态代理执行");
                // 利用反射执行目标方法   method.invoke(obj,args)
                Object result = method.invoke(calculator, args);
                // 目标方法返回值 必须返回到外界
                return result;
            }
        };

        Object proxy = Proxy.newProxyInstance(classLoader, classes, invocationHandler);

        return (Calculator) proxy;

    }

}
